package com.meshnetics.gb.type.impl.custom;

import com.meshnetics.gb.type.DataType;
import com.meshnetics.gb.type.DataValue;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Collection - any number of any data values can be hold inside of it. Can return types of values inside of collection.
 * All values and all values of desired type. Same or equal elemnts can be hold inside of colelction.
 *
 * @author AKovylin
 */
public abstract class CollectionDataValue extends CustomDataValue {
    private final DataValue[] elements;

    // no checks performed
    protected CollectionDataValue(CollectionDataType collectionType, DataValue[] elements) {
        super(collectionType);
        if (elements == null) {
            throw new NullPointerException("elements is null");
        }
        for (int i = 0; i < elements.length; i++) {
            if (elements[i] == null) {
                throw new NullPointerException("elements[" + i + "] is null");
            }
        }
        this.elements = elements;
    }

    public int getCollectionSize() {
        return elements.length;
    }

    public DataType[] getElementTypes() {
        Set types = new HashSet();
        for (int i = 0; i < elements.length; i++) {
            types.add(elements[i].getType());
        }
        return (DataType[]) types.toArray(new DataType[types.size()]);
    }

    public DataValue[] getElements() {
        return (DataValue[]) elements.clone();
    }

    public DataValue[] getElements(DataType elementType) {
        List res = new ArrayList();
        for (int i = 0; i < elements.length; i++) {
            if (elements[i].getType().equals(elementType)) {
                res.add(elements[i]);
            }
        }
        return (DataValue[]) res.toArray(new DataValue[res.size()]);
    }

    public DataValue getElement(int index) {
        return elements[index];
    }
}
